# Copyright (c) 2019 Presto Labs Pte. Ltd.
# Author: taekwon(originally from huobi_test.py)

import datetime
import logging
import pprint
import sys

from tornado import gen
from tornado.ioloop import IOLoop

from coin.base.config import Config
from coin.exchange.base.order_gateway import OrderSide, OrderType
from coin.exchange.deribit_v2.order_gateway import DeribitFuturesOrderGateway
from coin.exchange.deribit_v1.kr_rest.currency import DeribitCurrency
from coin.exchange.deribit_v1.kr_rest.futures_product import DeribitFuturesProduct

from coin.flow.simple_queue import SimpleQueue


class TestDriverBTC(object):
  def __init__(self, ioloop):
    self._ioloop = ioloop
    self._og = DeribitFuturesOrderGateway(
        [DeribitCurrency.FromStr('BTC')], [DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL')],
        Config.from_config_filename('/home/taekwon/deribit_api_key.json'))
    queue = SimpleQueue('q')
    self._og.start(queue, self._ioloop)
    self._ioloop.add_timeout(datetime.timedelta(seconds=5), self.print_balance)
    self._ioloop.add_timeout(datetime.timedelta(seconds=10), self.loop)

  def print_balance(self):
    if self._og.is_ready():
      print('------------------------')
      print(datetime.datetime.now())
      print('BTC', self._og.get_balance('BTC'))
      pprint.pprint(self._og.get_working_order())
    self._ioloop.add_timeout(datetime.timedelta(seconds=10), self.print_balance)

  @gen.coroutine
  def loop(self):
    self._og.cancel_all()
    yield gen.sleep(5)

    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    15000.,
                    100.,
                    OrderSide.SELL,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    3000.,
                    100.,
                    OrderSide.BUY,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    15000.,
                    100.,
                    OrderSide.SELL,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    3000.,
                    100.,
                    OrderSide.BUY,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    15000.,
                    100.,
                    OrderSide.SELL,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    3000.,
                    100.,
                    OrderSide.BUY,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    15000.,
                    100.,
                    OrderSide.SELL,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    3000.,
                    100.,
                    OrderSide.BUY,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    15000.,
                    100.,
                    OrderSide.SELL,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    3000.,
                    100.,
                    OrderSide.BUY,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    15000.,
                    100.,
                    OrderSide.SELL,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    3000.,
                    100.,
                    OrderSide.BUY,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    15000.,
                    100.,
                    OrderSide.SELL,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    3000.,
                    100.,
                    OrderSide.BUY,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    15000.,
                    100.,
                    OrderSide.SELL,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    3000.,
                    100.,
                    OrderSide.BUY,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    15000.,
                    100.,
                    OrderSide.SELL,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    3000.,
                    100.,
                    OrderSide.BUY,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    15000.,
                    100.,
                    OrderSide.SELL,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    3000.,
                    100.,
                    OrderSide.BUY,
                    OrderType.LIMIT)

    yield gen.sleep(10)
    # this should be not submitted due to wrong qty.
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    3000.,
                    95.,
                    OrderSide.BUY,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('BTC-USD.PERPETUAL'),
                    15000.,
                    9.,
                    OrderSide.SELL,
                    OrderType.LIMIT)

    yield gen.sleep(20)
    self._og.cancel_all()


class TestDriverETH(object):
  def __init__(self, ioloop):
    self._ioloop = ioloop
    self._og = DeribitFuturesOrderGateway(
        [DeribitCurrency.FromStr('ETH')], [DeribitFuturesProduct.FromStr('ETH-USD.PERPETUAL')],
        Config.from_config_filename('/home/taekwon/deribit_api_key.json'))
    queue = SimpleQueue('q')
    self._og.start(queue, self._ioloop)
    self._ioloop.add_timeout(datetime.timedelta(seconds=5), self.print_balance)
    self._ioloop.add_timeout(datetime.timedelta(seconds=10), self.loop)

  def print_balance(self):
    if self._og.is_ready():
      print('------------------------')
      print(datetime.datetime.now())
      print('ETH', self._og.get_balance('ETH'))
      pprint.pprint(self._og.get_working_order())
    self._ioloop.add_timeout(datetime.timedelta(seconds=10), self.print_balance)

  @gen.coroutine
  def loop(self):
    yield gen.sleep(5)

    self._og.submit(DeribitFuturesProduct.FromStr('ETH-USD.PERPETUAL'),
                    100.,
                    7.,
                    OrderSide.BUY,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('ETH-USD.PERPETUAL'),
                    100.,
                    3.,
                    OrderSide.BUY,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('ETH-USD.PERPETUAL'),
                    50.,
                    10.,
                    OrderSide.BUY,
                    OrderType.LIMIT)
    self._og.submit(DeribitFuturesProduct.FromStr('ETH-USD.PERPETUAL'),
                    70.,
                    100.,
                    OrderSide.BUY,
                    OrderType.LIMIT)

    yield gen.sleep(10)
    self._og.cancel_all()


def main(argv):
  ioloop = IOLoop.current()
  driver_btc = TestDriverBTC(ioloop)
  driver_eth = TestDriverETH(ioloop)
  try:
    ioloop.start()
  except KeyboardInterrupt:
    pass


if __name__ == '__main__':
  logging.basicConfig(level='DEBUG', format='%(levelname)s %(asctime)s %(name)s] %(message)s')
  sys.exit(main(sys.argv))
